import requests
import re
# from urllib import parse
from lxml import etree
# from threading import Thread
from multiprocessing.pool import ThreadPool
# import time
import json
import os
url = 'https://game.xiaomi.com/'
class GameInfo:
    def __init__(self,url):
        self.url  = url
        # 蘑菇代理的隧道订单
        appKey = "a01Oc2YxbmUzYWlEYWk2MzpHVFQ2aERqc3MwRElPeGJn"
        # 蘑菇隧道代理服务器地址
        ip_port = 'secondtransfer.moguproxy.com:9001'
        self.proxy = {"http": "http://" + ip_port, "https": "https://" + ip_port}
        self.headers = {
                           'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                            'Accept-Encoding': 'gzip, deflate, br',
                            'Accept - Language': 'zh - CN, zh;q = 0.9',
                            'User-Agent':'Mozilla/5.0(WindowsNT6.1;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/83.0.4103.97Safari/537.36',
                            "Proxy-Authorization": 'Basic ' + appKey,

        }
        self.a = 0

    def my_xpath(self,data,ruler): #xpath打包方法
        return etree.HTML(data).xpath(ruler)

    def get_interger(self, data): #转换数字
        try:
            res = int(data)
        except:
            try:
                res = float(data)
            except:
                res = data
        return res

    def is_empty(self, data):  # 处理数据为空的字段 str转int float
        if isinstance(data, list):
            if data != []:
                jieguo = data[0].strip()
                jieguo = self.get_interger(jieguo)
            else:
                jieguo = ''
        else:
            jieguo = self.get_interger(data)
        return jieguo

    def request_url(self,url,ma=0): #请求方法
        shu = ma
        shu += 1
        try:
            resp = requests.get(url=url, headers=self.headers, verify=False)#proxies=self.proxy,,timeout=5, allow_redirects=False
            if resp.status_code == 200 and resp:
                self.a = 0
                # print('hhhhh')
                return resp
            else:
                raise Exception
        except Exception :
            if shu >8:
                raise Exception('请求失败！')
            else:
                resp = self.request_url(url,shu)
                return resp

    def parse_content(self): #提取游戏列表
        resp = self.request_url(self.url).text
        # return resp
        if resp:
            game_url = self.my_xpath(resp,'//div[@wrap-id="view_load_wrapper"]//div[@class="game-list-sec"]/div[@class="game-list-ul"]/a/@href')
            game_url_list  = ['https://game.xiaomi.com'+i for i in game_url]
            return list(set(game_url_list))
        else:
            return []
    def get_detail_content(self): #请求失败循环请求
        m = 0
        while m<=9:
            game_url_list = self.parse_content()
            if game_url_list:
                return game_url_list
            else:
                m+=1
                print('list为空')
        # time.sleep(1)
        raise Exception('请求10次失败！')

    def get_ts_video_save(self,video_ts,url_host='https://mivideo.g.mi.com/',target=''): #下载ts视频代码封装，用于多线程
        video_ts_name = video_ts.split('/')[-1]
        if target:
            video_ts_url = url_host + target + video_ts
        else:
            video_ts_url = url_host + video_ts
        print(video_ts_url)
        content = self.request_url(video_ts_url).content  # requests获取视频
        self.save_file('E:\pythonGit\qiannv\\' + video_ts_name, content, 'wb')  # 保存片段视频

    def request_video_m3u8(self,resp,video_name): #小米游戏请求 https://game.xiaomi.com/
        item_content = re.findall(r'window.__INITIAL_STATE__= *(\{.*?\}\}\}),"devAppId":',resp)
        pool = ThreadPool(5)
        target = ''
        if item_content:
            item_content = item_content[0] + '}}}'
            item_content = json.loads(item_content)
            video_m3u8_url = item_content['game']['gameInfo']['detail']['videos']['720']['url']
            result = self.request_url(video_m3u8_url).text  #m3u8文件内容
            m3u8_name = video_m3u8_url.split('/')[-1]
            dir_name = 'E:\pythonGit\qiannv\\' + m3u8_name  #保存m3u8文件的全路径
            video_ts_list = re.findall(r',\n(.*?\.ts)',result) #获取片段视频地址
            video_ts_list = self.take_list(video_ts_list)
            file_ts = video_ts_list[0].split('/')
            if len(file_ts) != 1:
                target = self.is_empty(re.findall(r',\n(.*/).*?\.ts', result))
                result = result.replace(target, '')
            self.save_file(dir_name, result, 'w')
            print(video_ts_list)
            for video_ts in video_ts_list:
                pool.apply_async(self.get_ts_video_save,args=(video_ts,'https://mivideo.g.mi.com/')) #将下载片段视频任务添加到线程池
                # self.get_ts_video_save(video_ts)
                # Thread(target=self.get_ts_video_save,args=(video_ts,)).start()
            pool.close()
            pool.join()
            m = self.agin_get_ts_url(video_ts_list,'https://mivideo.g.mi.com/') #补存下载遗漏
            if m==0:
                self.hecheng_video(video_name,m3u8_name) #合成视频
            else:
                print('缺少ts_文件。')
            return video_ts_list,m3u8_name
        else:
            print('{}正则没有匹配到！'.format(video_name))
            return []

    def take_list(self,list_url): #处理列表内容
        lis = []
        for i in list_url:
            ts = i.split('/')[-1]
            lis.append(ts)
        return  lis

    def parse_page_one(self,keyword):
        url = 'http://www.zkk7.com/search/-------------.html?wd={}'.format(keyword)
        response = self.request_url(url)
        url_video = self.is_empty(self.my_xpath(response.text,'//div[@class="thumb"]/a/@href'))
        # print(url_video)
        if url_video:
            url_video = 'http://www.zkk7.com'+ url_video
            resp_video = self.request_url(url_video)
            video_url_list = ['http://www.zkk7.com'+i for i in self.my_xpath(resp_video.text,'//*[@id="playlist2"]/ul/li/a/@href')]
            video_name_list = self.my_xpath(resp_video.text,'//*[@id="playlist1"]/ul/li/a/text()')
            print(video_url_list)
            for url_v,name_v in zip(video_url_list,video_name_list):
                result = self.request_url(url_v)
                item_str = re.findall(r'var player_data=({.*?"note":""})</script>',result.text)[0]
                item = json.loads(item_str)
                del item_str
                url_video_m3u8 = item.get('url')
                print('----------->'+url_video_m3u8)
                url_video_m3u8 = url_video_m3u8.replace('hls.aoxtv.com/','')
                result_m3u8 = self.request_url(url_video_m3u8).text
                print(result_m3u8)
                m3u8_url = re.findall(r'\n(.*?\.m3u8)',result_m3u8)[0]
                if '/ppvod' not in m3u8_url:
                    url_host = url_video_m3u8.replace('index.m3u8','')
                    target = '{}/hls/'.format(m3u8_url.split('/')[0])
                else:
                    target = ''
                    url_host = url_video_m3u8.split('/2')[0]
                video_u = url_host + m3u8_url #meixianwan
                video_name = keyword + '-' + name_v + '.mp4'
                self.download_m3u8(video_u, url_host, video_name,target) #'800kb/hls/'
                # break
        else:
            print('没有搜索到相关内容。')

    def download_m3u8(self,video_m3u8_url,url_host,video_name,target =''): #樱花动漫 http://www.zkk7.com/
        pool = ThreadPool(10)
        result = self.request_url(video_m3u8_url).text  # m3u8文件内容
        m3u8_name = video_m3u8_url.split('/')[-1]
        dir_name = 'E:\pythonGit\qiannv\\' + m3u8_name  # 保存m3u8文件的全路径
        video_ts_list = re.findall(r',\n(.*?.ts)', result)  # 获取片段视频地址
        file_ts = video_ts_list[0].split('/')
        video_ts_list = self.take_list(video_ts_list)
        if len(file_ts) != 1:
            target = self.is_empty(re.findall(r',\n(.*/).*?.ts', result))
            result = result.replace(target, '')
        self.save_file(dir_name, result, 'w')
        print(video_ts_list)
        for video_ts in video_ts_list:
            video_ts = target + video_ts
            pool.apply_async(self.get_ts_video_save, args=(video_ts,url_host))  # 将下载片段视频任务添加到线程池
        pool.close()
        pool.join()
        m = self.agin_get_ts_url(video_ts_list,url_host,target)  # 补存下载遗漏
        if m == 0:
            self.hecheng_video(video_name, m3u8_name)  # 合成视频
            self.del_ts_video((video_ts_list,m3u8_name),'E:\pythonGit\qiannv')
        else:
            print('缺少ts_文件。')

    def hecheng_video(self,video_name,m3u8_name): #合成视频
        print('正在合成视频...')
        video_save_dir = 'E:\pythonGit\qiannv\\dm_video'
        self.mk_file(video_save_dir)
        video_save_dir = os.path.join(video_save_dir, video_name)
        print(video_save_dir)
        self.run_cmd(m3u8_name, video_save_dir, 'E:\pythonGit\qiannv')  #这里还需要写统计文件的个数，与ts的列表对比

    def agin_get_ts_url(self,ts_list,ts_host,target=''): #如果ts_url下载的视频片段有遗漏，补存下载  最好再递归下
        m = 0 #这个参数用来判断视频片段下载是否齐全，若为0则代表ts_视频片段已经下载齐全
        while m<=6:
            files = os.listdir('E:\pythonGit\qiannv')
            bianliang = set(ts_list) - set(files)
            if bianliang:
                for video_ts in bianliang:
                    self.get_ts_video_save(video_ts,ts_host,target)
                    m+=1
            else:
                print('ts_视频片段已经下载齐全。。。')
                m = 0
                break
        return m
    def del_ts_video(self,tuple_ts,current_dir): #删除ts文件
        video_ts_list,m3u8_name = tuple_ts
        video_ts_list.append(m3u8_name)
        for video_ts_name in video_ts_list:
            del_dir = os.path.join(current_dir, video_ts_name)
            # print(del_dir)
            if os.path.exists(del_dir):
                os.remove(del_dir)

    def mk_file(self,file):
        try:
            os.mkdir(file)
        except FileExistsError:
            pass

    def run_cmd(self,m3u8_url,video_dir_name,save_dir): #执行cmd命令
        os.chdir(save_dir) #切换目录
        mingling = 'ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,crypto,tcp" -i {} -c copy {}'.format(m3u8_url,video_dir_name)
        os.system(mingling)

    def save_file(self,dir,content,moshi):
        with open(dir,moshi) as f:
            f.write(content)

    def for_url_list(self,url_list): #请求每个游戏网址
        for url in url_list:
            shu = 0
            while shu < 10:
                z_resp = self.request_url(url).text
                if z_resp:
                    item = self.parse_detail_content(z_resp)
                    video_name = item.get('title') + '.mp4'
                    tuple_ts = self.request_video_m3u8(z_resp,video_name)
                    if tuple_ts:
                        self.del_ts_video(tuple_ts, 'E:\pythonGit\qiannv')
                    break
                else:
                    shu += 1
                    print('再次请求！')

    def parse_detail_content(self,z_resp): #解析网页，提取所需字段
        title = self.is_empty(self.my_xpath(z_resp, '//div[@class="basic-info"]/div[@class="detail-info"]/h1/text()'))
        logo = self.is_empty(self.my_xpath(z_resp,'//div[@class="basic-info"]/div[@class="game-icon"]/img/@src'))
        picture_url_list = ['https:'+i for i in self.my_xpath(z_resp,'//div[@id="pic_list"]/div/img/@src')]
        tags = self.my_xpath(z_resp,'//div[@class="label-list clearfix"]/span/text()')
        type_1 = tags[-1]
        version = self.is_empty(self.my_xpath(z_resp,'//div[@class="game-block"]/div[@class="game-label-block"]/div[2]/span[last()]/text()'))
        daxiao = self.is_empty(self.my_xpath(z_resp,'//div[@class="game-block"]/div[@class="game-label-block"]/div[2]/span[last()-1]/text()'))
        # daxiao = self.my_xpath(z_resp,'//div[@class="download d-btn"]/span/text()')[0]
        score = self.is_empty(self.my_xpath(z_resp,'//div[@class="basic-right"]/div[1]/text()'))
        short_desc = self.is_empty(self.my_xpath(z_resp,'//div[@class="section-game-desc"]/p[1]/text()'))
        kaifashang = self.is_empty(self.my_xpath(z_resp,'//div[@class="game-block"]/div[@class="game-label-block"]/p[2]/span/text()'))
        faxingshang = self.is_empty(self.my_xpath(z_resp,'//div[@class="game-block"]/div[@class="game-label-block"]/p[3]/span/text()'))
        item = {
            'id':'',
            'title':title,
            'logo':logo,
            'type':type_1,
            'banben':version,
            'content':short_desc,
            'daxiao':daxiao,
            'system':'安卓/苹果',
            'yuyan':'',
            'changshang':kaifashang,
            'faxingshang':faxingshang,
            'video':'',
            'banner':picture_url_list,
            'tags':tags,
            'score':score
        }
        print(item)
        return item
    def run(self):
        url_list = self.get_detail_content()
        self.for_url_list(url_list)


if __name__ == '__main__':
    gi = GameInfo(url)
    gi.parse_page_one('全职法师')
    # gi.download_m3u8('https://v2.szjal.cn/ppvod/6594C00CCCA956C8E88D704A60F15731.m3u8','鬼灭之刃-02.mp4')
    # gi.run()